package com.atguigu.mybatis.demo;

import com.atguigu.mybatis.bean.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by Smexy on 2022/10/10
 *
 *      SqlSessionFactory 是为了创建 SqlSession。
 *
 *      JDBC:  Connection，代表客户端和数据库的一个连接，通过这个连接可以发送sql给mysql服务器，接收mysql服务器返回的结果。
 *      Mybatis: SqlSession,代表客户端和数据库的一个连接,连上后产生一个Session,这个session可以把客户端的sql
 *                  给mysql服务器，接收mysql服务器返回的结果。
 *
 *                  程序开始的地方。
 *
 *   -------------------------------------
 *      orm映射在代码中的封装规则：
 *         sqlSession.selectOne("feichangbang.sql1", 1);
 *
 *         select * from employee where id = 1
 *
 *      id  last_name  gender  email
 * ------  ---------  ------  --------------
 *      1  Tom        male    Tom@163.com
 *
 *      resultType="com.atguigu.mybatis.bean.Employee"
 *
 *      利用反射，根据com.atguigu.mybatis.bean.Employee，调用空参构造器，获取
 *            Employee e =  new Employee();
 *      把查到的数据封装到e中:
 *              e.setXxx(yyy):  Xxx是查询的列名， yyy是查询的列值
 *
 *              e.setId(1);
 *              e.setLast_name("Tom");
 *              ...
 *
 *  =================================================
 *
 *   弊端:
 *          ①对传入的占位符参数没有严格的类型检查，导致编译时无法检查入参，运行时出错
 *          ②返回值类型是Object，还需要强转，麻烦
 *
 *
 *   解决：   自己编写 Dao，使用自己规定的方法，明确返回值类型和入参。
 *
 *             class MyDao{
 *
 *                 public Employee xx(Integer id);
 *
 *             }
 *
 *            接口式编程。
 *              自己编写Dao接口，调用自己编写的接口实例执行 CRUD
 *
 *
 *
 *
 */
public class MybatisHelloWorld
{
    public static void main(String[] args) throws IOException {

        //加载你配置的全局配置文件，才只能知道你的数据库怎么练
        //类路径下的配置文件名叫什么
        String resource = "config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //获取一个SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*
            发送sql到mysql

            selectOne(String statement, Object parameter)
                String statement: 发给mysql的语句。
                            使用编写了sql语句的xml文件中的  namespace.id 代表一个语句(全类名)
                 Object parameter： 语句中添加的参数
         */
        Object o = sqlSession.selectOne("feichangbang.sql1", sqlSession);

        Employee employee = (Employee) o;

        System.out.println(employee);

        sqlSession.close();


    }
}
